package app.myproject.action.bookmark;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import app.myproject.dao.BookmarkDAOImpl;
import app.myproject.model.BookmarkVO;
import app.myproject.util.CustomeKeyEditor;
import app.myproject.validator.BookmarkValidator;


@Controller
@RequestMapping("/bookmark")
@SessionAttributes(value={"bookmark"})
public class BookmarkController {

	@Resource 
	BookmarkValidator validator;
	
	@Autowired
	public BookmarkController(BookmarkValidator bookmarkValidator){
		this.validator = bookmarkValidator;
	}
	
	@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
	
	    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	    dateFormat.setLenient(false);

	    binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
	    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	    binder.registerCustomEditor(List.class, new CustomCollectionEditor(List.class));
	    binder.registerCustomEditor(com.google.appengine.api.datastore.Key.class, new CustomeKeyEditor());

	}
	
	protected boolean validate(BookmarkVO bookmark, BindingResult result) {
		validator.validate(bookmark, result);
		if (result.hasErrors()) {
			printErrorLog(result);
			return false;
		}
		return true;
	}
	
	protected void printErrorLog(BindingResult result) {
		System.out.println("errors");
		for (ObjectError error:result.getAllErrors()) {
			System.out.println(error.getDefaultMessage());
		}
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public String forward(ModelMap model) {
		return "forward:list";
	}
	
	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String toAdd(ModelMap model) {
		System.out.println("toAdd");
		
		BookmarkDAOImpl dao = new BookmarkDAOImpl();
		BookmarkVO bookmark = dao.create();
		model.addAttribute("bookmark",bookmark);
		
		return "bookmark/add";
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public ModelAndView add(@ModelAttribute("bookmark") BookmarkVO bookmark, BindingResult result, SessionStatus status) {
		System.out.println("add");
				
		if (validate(bookmark, result)) {
			bookmark.setCreated(new Date());
			BookmarkDAOImpl dao = new BookmarkDAOImpl();
			dao.save(bookmark);
			status.setComplete();			
		}
		else {
			return new ModelAndView("bookmark/add");
		}
		
		return new ModelAndView("redirect:/bookmark/list");
	}

	@RequestMapping(value = "/update/{encodedKey}", method = RequestMethod.GET)
	public String toEdit(@PathVariable String encodedKey, ModelMap model) {
		System.out.println("toEdit");
		
		BookmarkDAOImpl dao = new BookmarkDAOImpl();
		BookmarkVO bookmark = dao.find(encodedKey);
		model.addAttribute("bookmark", bookmark);
		
		return "bookmark/update";

	}

	@RequestMapping(value = "/update/{encodedKey}", method = RequestMethod.POST)
	public ModelAndView edit(@PathVariable String encodedKey, @ModelAttribute("bookmark") BookmarkVO bookmark, BindingResult result, SessionStatus status) {
		System.out.println("edit");
		
		if (validate(bookmark, result)) {
			BookmarkDAOImpl dao = new BookmarkDAOImpl();
			dao.update(bookmark);
			status.setComplete();
		} 
		else {
			return new ModelAndView("bookmark/update");			
		}

		return new ModelAndView("redirect:/bookmark/list");

	}

	@RequestMapping(value = "/delete/{encodedKey}", method = RequestMethod.GET)
	public ModelAndView delete(@PathVariable String encodedKey, ModelMap model) {
		System.out.println("delete");
		
		BookmarkDAOImpl dao = new BookmarkDAOImpl();
		dao.deleteById(encodedKey);

		return new ModelAndView("redirect:/bookmark/list");

	}

	// get all bookmarks
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String list(ModelMap model) {

		System.out.println("list");
		
		BookmarkDAOImpl dao = new BookmarkDAOImpl();
		List<BookmarkVO> list = dao.list();	
		model.addAttribute("bookmarkList", list);
		
		System.out.println("result: " + list.size());

		return "bookmark/list";

	}

}